//: Playground - noun: a place where people can play

import Cocoa

var str = "Hello, playground"

// logical NOT
var a : String = "pumpkin"
var b : String = "watermelon"

if a == b {
    print("The strings match!")
}

if !(a == b) {
    print("The strings don't match!")
}

// logical AND
let c = true
let d = true

if c == true && d == true {
    print("both are true!")
}

// logical OR
let e = true
let f = false

if e == true || f == true {
    print("one or the other is true!")
}

func areValuesEqual<T: Equatable>(firstValue: T, secondValue: T) -> Bool {
    return firstValue == secondValue
}

areValuesEqual(3, secondValue: 3)
areValuesEqual(3.3, secondValue: 1.4)
areValuesEqual("first", secondValue: "second")

struct Matrix2x2 {
    var a11 = 0.0, a12 = 0.0
    var a21 = 0.0, a22 = 0.0
}

func + (left: Matrix2x2, right: Matrix2x2) -> Matrix2x2 {
    return Matrix2x2(a11: left.a11 + right.a11,
        a12: left.a12 + right.a12,
        a21: left.a21 + right.a21,
        a22: left.a22 + right.a22)
}

func * (left: Matrix2x2, right: Matrix2x2) -> Matrix2x2 {
    return Matrix2x2(a11: left.a11 * right.a11 + left.a12 * right.a21,
        a12: left.a11 * right.a12 + left.a12 * right.a22,
        a21: left.a21 * right.a11 + left.a22 * right.a21,
        a22: left.a21 * right.a12 + left.a22 * right.a22)
}

var A : Matrix2x2 = Matrix2x2(a11: 1, a12: 3, a21: 5, a22: 6)
var B : Matrix2x2 = Matrix2x2(a11: 2, a12: 6, a21: 4, a22: 8)

var C = A + B

var E : Matrix2x2 = Matrix2x2(a11: 2, a12: 3, a21: 1, a22: 4)
var F : Matrix2x2 = Matrix2x2(a11: 3, a12: 2, a21: 1, a22: -6)

var G = E * F

1 == 3

// testing the identity of objects
class Test1 {
}

class Test2 {
}

var t1 : Test1 = Test1()
var t2 : Test2 = Test2()
var t3 : Test2 = Test2()
var t4 = t2

t1 === t2
t2 === t3
t4 === t2
t4 !== t2

// Error Handling Example
enum PasswordError : ErrorType {
    case TooShort
    case NoUppercaseCharacter
    case NoLowercaseCharacter
}

func checkValidPassword(password : String) throws -> Bool {
    var containsUppercase : Bool = false
    var containsLowercase : Bool = false
    
    // check if password is too short
    if password.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) < 8 {
        throw PasswordError.TooShort
    }
    
    for c in password.characters {
        if c >= "A" && c < "Z"  {
            containsUppercase = true
            break
        }
    }

    for c in password.characters {
        if c >= "a" && c < "z" {
            containsLowercase = true
            break
        }
    }
    
    if containsLowercase == false {
        throw PasswordError.NoLowercaseCharacter
    }

    if containsUppercase == false {
        throw PasswordError.NoUppercaseCharacter
    }
    
    return true
}

func tryPassword(password: String) {
    do {
        try checkValidPassword(password)
        print("Password is ok")
    } catch {
        print("Error: \(error)")
    }
}

tryPassword("2Short")
